﻿using System;
using System.ComponentModel;

namespace Maria.Common.Aspects
{
    public interface IFirePropertyChanged
    {
        void OnPropertyChanged(string propertyName);
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class SupportDataBindingAttribute : Attribute
    {
        public SupportDataBindingAttribute() { }
    }

    /// <summary>
    /// Свойство, на которое повешен атрибут, изменяется при изменении свойств,
    /// перечисленных в параметрах атрибута
    /// </summary>
    public class DependOnAttribute : Attribute
    {
        public DependOnAttribute(string p1) { }
        public DependOnAttribute(string p1, string p2) { }
        public DependOnAttribute(string p1, string p2, string p3) { }
        public DependOnAttribute(string p1, string p2, string p3, string p4) { }
        public DependOnAttribute(string p1, string p2, string p3, string p4, string p5) { }
        public DependOnAttribute(string p1, string p2, string p3, string p4, string p5, string p6) { }
        public DependOnAttribute(string p1, string p2, string p3, string p4, string p5, string p6, string p7) { }
        public DependOnAttribute(string p1, string p2, string p3, string p4, string p5, string p6, string p7, string p8) { }
        public DependOnAttribute(string[] p) { }
    }

    /// <summary>
    /// При завершении сеттера свойства, на которое повешен этот атрибут,
    /// также вызываются FirePropertyChanged по всем свойствам,
    /// перечисленных в параметрах атрибута
    /// </summary>
    public class AddPropertyChangedAttribute : Attribute
    {
        public AddPropertyChangedAttribute(string p1) { }
        public AddPropertyChangedAttribute(string p1, string p2) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3, string p4) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3, string p4, string p5) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3, string p4, string p5, string p6) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3, string p4, string p5, string p6, string p7) { }
        public AddPropertyChangedAttribute(string p1, string p2, string p3, string p4, string p5, string p6, string p7, string p8) { }
        public AddPropertyChangedAttribute(string[] p) { }
    }

    public static class NotifyCilCodeSamples
    {
        public static void add_handler(ref PropertyChangedEventHandler ev, PropertyChangedEventHandler par)
        {
            // todo: нужно передавать instance INotifyPropertyChanged и делать ей lock
            ev += par;
        }

        public static void remove_handler(ref PropertyChangedEventHandler ev, PropertyChangedEventHandler par)
        {
            // todo: нужно передавать instance INotifyPropertyChanged и делать ей lock
            ev -= par;
        }

        public static void fire_handler(object source, PropertyChangedEventHandler handler, string propertyName)
        {
            if (handler != null)
                handler(source, new PropertyChangedEventArgs(propertyName));
        }
    }

    public static class Types
    {
        public static string StringType() { return ""; }
        public static void VoidType() { }
        public static INotifyPropertyChanged NotifyType() { return null; }
        public static PropertyChangedEventHandler ChangedType() { return null; }
        public static Type SystemType() { return null; }
        public static object ObjectType() { return null; }
        public static object[] ObjArrayType() { return null; }
    }
}
